package com.tong.hao.ac.service;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration;
import org.springframework.boot.web.servlet.ServletComponentScan;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

/**
 * @ClassName HaoServiceApplication
 * @Author 友野浩二
 * @Description 联机交易AC(account)模块启动类
 * @Version 1.0
 *
 * <pre>
 * 1-@SpringBootApplication
 *      声明让spring boot自动给程序进行必要的配置,
 *      等价于以默认属性使用@Configuration,@EnableAutoConfiguration和@ComponentScan。
 *      在没有配置数据源的时候需要添加exclude = DataSourceAutoConfiguration.class(取消自动数据源自动配置),防止启动报错
 * 2-@controller
 *      返回的是字符串,或者是字符串匹配的模板名称,即直接渲染视图,与html页面配合使用的。
 *      在这种情况下,前后端的配合要求比较高,java后端的代码要结合html的情况进行渲染,使用model对象(或者modelandview)的数据将填充user视图中的相关属性,
 *      然后展示到浏览器,这个过程也可以称为渲染;
 *   【注意】：@Controller用来响应页面,@Controller必须配合模版来使用。spring-boot支持多种模版引擎包括：
 *              1)- FreeMarker
 *              2)- Groovy
 *              3)- Thymeleaf(Spring 官网使用这个)
 *              4)- Velocity
 *              5)- JSP(貌似Spring Boot官方不推荐,STS创建的项目会在src/main/resources下有个templates目录,这里就是让我们放模版文件的,然后并没有生成诸如 SpringMVC中的webapp目录)
 *              以Thymeleaf为例介绍使用模版，具体步骤如下：
 *                  第一步：在pom.xml文件中添加如下模块依赖：
 * 			            <artifactId>spring-boot-starter-thymeleaf</artifactId>
 * 			        第二步：控制器代码如下(启动类中的family方法)
 * 			        第三步：在resources目录的templates目录下添加一个hello.html文件
 * 3-@RestController
 *      该注解相当于@Controller + @ResponseBody，默认方法接口返回json格式的数据，在返回前使用Jackson将对象序列化为json；
 *      当在形参中使用@RequestBody注解时，默认使用Jackson将json反序列化为对象。
 * 5-@ServletComponentScan
 *      过滤器和监听器需要在启动类中加入该注解进行自动注册。
 * 6-@EnableAspectJAutoProxy(proxyTargetClass = true)
 *      开启增强代理,AOP切面
 *      org.springframework.boot.autoconfigure.aop.AopAutoConfiguration 类中默认开启 CglibAutoProxyConfiguration
 * 7-@Spring管理mapper类的两种方式：
 *      1).在每个mapper类上面添加注解@Mapper;
 *      2).第一种方式太麻烦,如果mapper类太多的话就显得太麻烦,所以建议在spring boot的启动类上使用@MapperScan扫描Mapper类的包路径。
 * 8- 服务发现@EnableDiscoveryClient 和 @EnableEurekaClient的区别: 用法基本一致。
 *        spring cloud中discovery service有许多种实现(eureka、consul、zookeeper等)。
 *        @EnableDiscoveryClient 基于spring-cloud-commons；@EnableEurekaClient基于spring-cloud-netfix。
 *        简单说，如果选用的服务注册中心是eureka，那么就推荐@EnableEurekaClient，如果是其他注册中心，那么推荐使用@EnableDiscoveryClient。
 *        @EnableEurekaClient 的使用场景较为单一。
 * 9-@EnableFeignClients : 启用feign进行远程调用
 *     Feign是一个声明式Web Service客户端，使用Feign能让编写Web Service客户端更加简单。
 *     使用方法: 定义一个接口，然后在上面添加注解。同时也支持JAX-RS标准的注解。Feign也支持可拔插式的编码器和解码器。
 *     Spring Cloud对Feign进行了封装，使其支持了Spring MVC标准注解和HttpMessageConverters。Feign可以与Eureka和Ribbon组合使用以支持负载均衡。
 * </pre>
 */
@Api(tags = "TONG ONLINE AC")
@Controller
@ServletComponentScan(basePackages = {"com.tong.hao.common.configuration.filter", "com.tong.hao.common.configuration.listener"})
@ComponentScan(basePackages = {"cn.buddha.jec", "com.tong.hao.ac", "com.tong.hao.common.configuration"})
@MapperScan(basePackages = {"cn.buddha.jec.db.dao", "com.tong.hao.ac.db.dao"})
@EnableAspectJAutoProxy(proxyTargetClass = true)
@EnableEurekaClient
@EnableFeignClients(basePackages = {})
/**
 * 工程中依赖了 spring-boot-starter-data-redis,但是平时开发的时候又不怎么用到的话,可以在这里使用 exclude 属性剔除掉
 */
@SpringBootApplication// (exclude = {RedisAutoConfiguration.class})
@Slf4j
public class HaoAcServiceApplication {

    public static void main(String[] args) {
        SpringApplication.run(HaoAcServiceApplication.class, args);
        log.info("<<<<======== Tong Online Ac Service started ========>>>>");
    }

    @ApiOperation(value = "TongOnlineMain")
    @RequestMapping("/family")
    public String family() {
        // family是模板名,对应src/main/resources/templates下的family.html
        return "family.html";
    }

    @ApiOperation(value = "爸爸")
    @ResponseBody
    @RequestMapping(value = "/", method = RequestMethod.GET)
    public String home() {
        return "This is tong online service ac!";
    }

}
